#include "HttpRouter.h"
#include <iostream>
#include <fstream>

using std::cout;
using std::endl;

HttpRouter::HttpRouter()
{
}

HttpRouter::~HttpRouter()
{
}

void HttpRouter::get(const std::string& path, HttpHandler handler)
{
    route(HttpMethod::GET, path, handler);
}

void HttpRouter::post(const std::string& path, HttpHandler handler)
{
    route(HttpMethod::POST, path, handler);
}

void HttpRouter::put(const std::string& path, HttpHandler handler)
{
    route(HttpMethod::PUT, path, handler);
}

void HttpRouter::del(const std::string& path, HttpHandler handler)
{
    route(HttpMethod::DELETE, path, handler);
}

void HttpRouter::options(const std::string& path, HttpHandler handler)
{
    route(HttpMethod::OPTIONS, path, handler);
}

void HttpRouter::route(HttpMethod method, const std::string& path, HttpHandler handler)
{
    _routes.emplace_back(method, path, handler);
}

void HttpRouter::serveStatic(const std::string& urlPrefix, const std::string& localPath)
{
    _staticUrlPrefix = urlPrefix;
    _staticLocalPath = localPath;
    
    // 确保URL前缀以/结尾
    if (!_staticUrlPrefix.empty() && _staticUrlPrefix.back() != '/') {
        _staticUrlPrefix += '/';
    }
    
    // 确保本地路径以/结尾
    if (!_staticLocalPath.empty() && _staticLocalPath.back() != '/') {
        _staticLocalPath += '/';
    }
}

bool HttpRouter::handleRequest(const HttpRequest& request, HttpResponse& response)
{
    // 执行中间件
    for (auto& middleware : _middlewares) {
        if (!middleware(request, response)) {
            return true; // 中间件拦截了请求
        }
    }
    
    // 检查静态文件服务
    if (!_staticUrlPrefix.empty() && 
        request.getPath().find(_staticUrlPrefix) == 0) {
        std::string relativePath = request.getPath().substr(_staticUrlPrefix.length());
        std::string filePath = _staticLocalPath + relativePath;
        handleStaticFile(filePath, response);
        return true;
    }
    
    // 查找匹配的路由
    bool pathMatched = false;
    for (const auto& route : _routes) {
        if (matchRoute(route, request)) {
            if (route.method == request.getMethod()) {
                // 找到匹配的路由，执行处理器
                route.handler(request, response);
                return true;
            } else {
                pathMatched = true; // 路径匹配但方法不匹配
            }
        }
    }
    
    // 处理错误情况
    if (pathMatched) {
        handleMethodNotAllowed(response);
    } else {
        handleNotFound(response);
    }
    
    return true;
}

void HttpRouter::use(Middleware middleware)
{
    _middlewares.push_back(middleware);
}

bool HttpRouter::matchRoute(const Route& route, const HttpRequest& request)
{
    return std::regex_match(request.getPath(), route.regex);
}

void HttpRouter::handleNotFound(HttpResponse& response)
{
    response.setStatusCode(HttpStatusCode::NOT_FOUND);
    response.setJsonContent(R"({"error": "Not Found", "code": 404})");
}

void HttpRouter::handleMethodNotAllowed(HttpResponse& response)
{
    response.setStatusCode(HttpStatusCode::METHOD_NOT_ALLOWED);
    response.setJsonContent(R"({"error": "Method Not Allowed", "code": 405})");
}

void HttpRouter::handleStaticFile(const std::string& filePath, HttpResponse& response)
{
    std::ifstream file(filePath, std::ios::binary);
    if (!file.is_open()) {
        handleNotFound(response);
        return;
    }
    
    // 读取文件内容
    std::string content((std::istreambuf_iterator<char>(file)),
                         std::istreambuf_iterator<char>());
    
    // 设置Content-Type
    response.setContentType(getContentType(filePath));
    response.setBody(content);
}

std::string HttpRouter::getContentType(const std::string& filePath)
{
    size_t dotPos = filePath.find_last_of('.');
    if (dotPos == std::string::npos) {
        return "application/octet-stream";
    }
    
    std::string extension = filePath.substr(dotPos + 1);
    
    if (extension == "html" || extension == "htm") {
        return "text/html; charset=utf-8";
    } else if (extension == "css") {
        return "text/css; charset=utf-8";
    } else if (extension == "js") {
        return "application/javascript; charset=utf-8";
    } else if (extension == "json") {
        return "application/json; charset=utf-8";
    } else if (extension == "png") {
        return "image/png";
    } else if (extension == "jpg" || extension == "jpeg") {
        return "image/jpeg";
    } else if (extension == "gif") {
        return "image/gif";
    } else if (extension == "svg") {
        return "image/svg+xml";
    } else if (extension == "ico") {
        return "image/x-icon";
    } else if (extension == "txt") {
        return "text/plain; charset=utf-8";
    } else if (extension == "xml") {
        return "application/xml; charset=utf-8";
    }
    
    return "application/octet-stream";
}